/*
 * +----------------------------------------------------------------------
 * | Copyright (c) 奇特物联 2021-2022 All rights reserved.
 * +----------------------------------------------------------------------
 * | Licensed 未经许可不能去掉「奇特物联」相关版权
 * +----------------------------------------------------------------------
 * | Author: xw2sy@163.com
 * +----------------------------------------------------------------------
 */
package cc.iotkit.plugins.soulcall.service;

import cc.iotkit.common.utils.StringUtils;
import cc.iotkit.model.device.DeviceInfo;
import cc.iotkit.plugin.core.thing.IThingService;
import cc.iotkit.plugin.core.thing.actions.DeviceState;
import cc.iotkit.plugin.core.thing.actions.EventLevel;
import cc.iotkit.plugin.core.thing.actions.up.DeviceStateChange;
import cc.iotkit.plugin.core.thing.actions.up.EventReport;
import cc.iotkit.plugin.core.thing.actions.up.PropertyReport;

import cc.iotkit.plugins.soulcall.conf.SoulcallConfig;
import cc.iotkit.plugins.soulcall.intercepter.HealthInboundInterceptor;
import cc.iotkit.plugins.soulcall.intercepter.HealthOutboundInterceptor;
import com.gitee.starblues.bootstrap.annotation.AutowiredType;
import com.gitee.starblues.core.PluginInfo;
import io.vertx.core.AbstractVerticle;
import io.vertx.core.Handler;
import io.vertx.core.http.HttpClient;
import io.vertx.core.http.HttpServer;
import io.vertx.core.http.HttpServerRequest;
import io.vertx.core.http.HttpServerResponse;
import io.vertx.core.json.JsonArray;
import io.vertx.core.json.JsonObject;
import io.vertx.core.net.NetClient;
import io.vertx.core.net.NetServer;
import io.vertx.core.net.NetSocket;
import io.vertx.core.streams.Pump;
import io.vertx.ext.web.Router;
import io.vertx.ext.web.RoutingContext;
import io.vertx.ext.web.handler.BodyHandler;
import io.vertx.ext.web.proxy.handler.ProxyHandler;
import io.vertx.httpproxy.HttpProxy;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.util.*;
import java.util.function.Predicate;

/**
 * soulcall官方协议文档：
 *
 *
 * @author lishj
 */
@Slf4j
@Component
@Data
public class SoulcallProxyVerticle extends AbstractVerticle{

    private SoulcallConfig config;

    @Autowired
    @AutowiredType(AutowiredType.Type.MAIN_PLUGIN)
    private IThingService thingService;

    @Autowired
    private PluginInfo pluginInfo;

    private static final Set<String> DEVICE_ONLINE = new HashSet<>();

//    private final HealthInboundInterceptor healthInboundInterceptor;
//    private final HealthOutboundInterceptor healthOutboundInterceptor;

    private HttpServer httpServer;
    private HttpClient proxyClient;
    private HttpClient proxyClient2;
    private HttpProxy healthProxy;
    private HttpProxy linxiHttpProxy;

    @Override
    public void start() {
        httpServer = vertx.createHttpServer();
        Router proxyRouter = Router.router(vertx);
        httpServer.requestHandler(proxyRouter);
        httpServer.listen(config.getProxyPort(), ar -> {
            if (ar.succeeded()) {
                log.info("http server is listening on port " + ar.result().actualPort());
            } else {
                log.error("Error on starting the server", ar.cause());
            }
        });

        proxyClient = vertx.createHttpClient();
        healthProxy = HttpProxy.reverseProxy(proxyClient);
        healthProxy.origin(config.getMode()==0?config.getHealthTestPort():config.getHealthPort(),
                config.getMode()==0?config.getHealthTestHost():config.getHealthHost());
        proxyClient2 = vertx.createHttpClient();
        linxiHttpProxy = HttpProxy.reverseProxy(proxyClient2);
        linxiHttpProxy.origin(config.getMode()==0?config.getLinxiTestPort():config.getLinxiPort(),
                config.getMode()==0?config.getLinxiTestHost():config.getLinxiHost());
        //代理设置
        proxyRouter.post(LinxiSignHelper.ALARM_PATH).handler(ProxyHandler.create(healthProxy));
        proxyRouter.post(LinxiSignHelper.EVENT_PATH).handler(ProxyHandler.create(healthProxy));
        proxyRouter.post(LinxiSignHelper.ADD_DEVICE).handler(ProxyHandler.create(linxiHttpProxy));
        proxyRouter.post(LinxiSignHelper.DEL_DEVICE).handler(res->{
            log.info(res.request().absoluteURI());
            res.next();

        })
                .handler(ProxyHandler.create(linxiHttpProxy));
    }

    @Override
    public void stop() {
        if(Objects.nonNull(httpServer)){
            httpServer.close();
        }
    }
}
